/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package BL;

import BD.DaoConfig;
import BD.interfaces.PaginaDao;
import BD.interfaces.TerminoDao;
import BD.interfaces.TerminoVacioDao;
import BD.interfaces.TerminoWebDao;
import BE.Pagina;
import BE.Termino;
import BE.TerminoVacio;
import BE.TerminoWeb;
import BE.Terminoxpagina;
import com.ibatis.dao.client.DaoManager;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author externo.drisco
 */
public class AlmacenamientoBL {

    private DaoManager daoManager;

   public AlmacenamientoBL(){
       daoManager = DaoConfig.getDaoManager();
   }


    public void almacenarPaginasCrawler() {
        
        List<Pagina> arrPaginaTemp = obtenerPaginas();
        int intIdPagTemp =0;
        int inicio = 0;
        int fin = 0;
        int finTotal =0;
        String strPaginaHead ="";
        String strBodyPagina="";



        for(Pagina pag:arrPaginaTemp)
        {
            intIdPagTemp = pag.getIdpagina();
            guardarPagina(pag);
            String htmlPagina = pag.getContenidopagina();

            inicio = htmlPagina.indexOf("<head");

            finTotal=inicio+5;

            while(finTotal>0){
                fin = htmlPagina.indexOf("</head>",finTotal);

                if(fin>0){
                    finTotal=fin+7;
                }
                else{
                    fin=finTotal-7;
                    finTotal=-1;
                }
            }

            

            strPaginaHead = htmlPagina.substring(inicio, fin+7);
            strBodyPagina = htmlPagina.substring(fin+7,htmlPagina.length());

            String [] arrTerminosClavesHead = obtenerKeywordHead(strPaginaHead);/////////OJO ANALIZAR KE HACER KON LOS TERMINOS EN CABECERA

            String resultado = obtenerPaginaHtml(strBodyPagina);
            String [] arrTerminos = resultado.split(" ");
            ArrayList<Terminoxpagina> arrPalabras = prepararAlmacenamiento(arrTerminos,pag);
            guardarTerminos(arrPalabras);
            eliminarPag(intIdPagTemp);
        }
        arrPaginaTemp.clear();

    }

    private List<Pagina> obtenerPaginas(){

        PaginaDao objPaginaDao = (PaginaDao)daoManager.getDao(PaginaDao.class);

        return objPaginaDao.obtenerPaginasTemp();
    }

    private void guardarPagina(Pagina pag){

        PaginaDao objPaginaDao = (PaginaDao)daoManager.getDao(PaginaDao.class);
        objPaginaDao.insertarPagina(pag);
    }

    private String[] obtenerKeywordHead(String strPaginaHead){

        int indKeyword = strPaginaHead.toLowerCase().indexOf("keyword");
        int indContent=0;
        int inicio=0;
        int fin=0;
        String keywords="";

        if(indKeyword>-1){
            indContent = strPaginaHead.toLowerCase().indexOf("content",indKeyword);
            fin = strPaginaHead.toLowerCase().indexOf("\"",indContent+9);
            keywords = strPaginaHead.toLowerCase().substring(indContent+9, fin);
        }

        int indDescripcion = strPaginaHead.toLowerCase().indexOf("description");
        String descripcion = "";

        if(indDescripcion>-1){
            indContent = strPaginaHead.toLowerCase().indexOf("content",indDescripcion);
            fin = strPaginaHead.toLowerCase().indexOf("\"",indContent+9);
            descripcion = strPaginaHead.toLowerCase().substring(indContent+9, fin);
        }

        inicio = strPaginaHead.toLowerCase().indexOf("title");
        fin = strPaginaHead.toLowerCase().indexOf("title",(inicio+5));

        String strTitulo = strPaginaHead.substring(inicio+6, fin-2);
        strTitulo = strTitulo.replaceAll("|","");
        strTitulo = strTitulo.replaceAll(" ", ",");

        descripcion = descripcion.replaceAll(" ", ",");

        keywords = keywords+","+descripcion+","+strTitulo;

        String[] arrTerminos = keywords.split(",");

        return arrTerminos;
    }


    private String obtenerPaginaHtml(String strPagina)
    {
        String strPaginaSinHtml="";
        int inicio=0;
        int fin=0;
        int indScript = 0;

        while(!strPagina.equals(""))
        {

            inicio = strPagina.indexOf("<");
            fin = strPagina.indexOf(">");
            indScript = strPagina.toLowerCase().indexOf("script");

            if((inicio+1)==indScript){

                fin = strPagina.toLowerCase().indexOf("script>",indScript+6);
                strPagina = strPagina.substring(fin+7, strPagina.length());
            }
            else{
                if((inicio==-1)||(fin==-1))
                {
                    break;
                }

                if(inicio!=0)
                {
                    strPaginaSinHtml = strPaginaSinHtml + strPagina.substring(0, inicio).trim();

                    if((strPaginaSinHtml.length()>0)&&(strPaginaSinHtml.charAt(strPaginaSinHtml.length()-1)!=' ')){
                            strPaginaSinHtml = strPaginaSinHtml + " ";
                    }

                    strPagina = strPagina.substring(fin+1, strPagina.length());
                }
                else
                {
                    strPagina = strPagina.substring(fin+1, strPagina.length());
                }
            }
        }

        strPaginaSinHtml = removerCodigoWeb(strPaginaSinHtml);


        return strPaginaSinHtml.toLowerCase().trim();
    }

    private String removerCodigoWeb(String strPagina){

        TerminoWebDao objTermWebDao = (TerminoWebDao)daoManager.getDao(TerminoWebDao.class);
        List<TerminoWeb> arrTerminoWeb = objTermWebDao.seleccionarTerminoWeb();

        for(TerminoWeb t: arrTerminoWeb){

            strPagina = strPagina.replaceAll(t.getCodigoweb(),t.getCodigoreal());

        }

        return strPagina;
    }



    private ArrayList<Terminoxpagina>  prepararAlmacenamiento(String [] arrTerminos,Pagina pag){

        List<String> arrTermSinVacios = eliminarTerminosVacios(arrTerminos);

        ArrayList<Terminoxpagina> arrTermxPag = obtenerFrecuencia(arrTermSinVacios,pag);

        calcularPesos(arrTermxPag);

        return arrTermxPag;
    }

    private List<String> eliminarTerminosVacios(String [] arrTerminos){

        List<String> arrPalabras = new ArrayList<String>();
        TerminoVacioDao objTermVacioDao = (TerminoVacioDao)daoManager.getDao(TerminoVacioDao.class);

        List<TerminoVacio> arrTerminoVacio = objTermVacioDao.seleccionarTerminoVacio();

        for(int i=0;i<arrTerminos.length;i++)
        {
            if(!arrTerminos[i].trim().equals(""))
            {
                if(NoEsVacio(arrTerminos[i],arrTerminoVacio))
                arrPalabras.add(arrTerminos[i]);
            }
        }
        return arrPalabras;
    }


    private boolean NoEsVacio(String termino,List<TerminoVacio> arrTerminoVacio){

        termino=termino.replace("[", "");
        termino=termino.replace("]", "");
        termino=termino.replace("{", "");
        termino=termino.replace("}", "");
        termino=termino.replace("(", "");
        termino=termino.replace(")", "");
        termino=termino.replace("|", "");
        termino=termino.replace(",", "");
        termino=termino.replace(":", "");
        termino=termino.replace(".", "");
        termino=termino.replace(";", "");
        termino=termino.replace("/", "");
        termino=termino.replace("-", "");
        termino=termino.replace("\"", "");
        termino=termino.replace("'", "");
        termino= termino.trim();

        if(!termino.equals("")){
            for(int i=0;i<arrTerminoVacio.size();i++)
            {
                if(termino.toLowerCase().equals(arrTerminoVacio.get(i).getTermino().toLowerCase()))
                {
                    return false;
                }
            }
        }
        else{
            return true;
        }

        return true;
    }


    private ArrayList<Terminoxpagina> obtenerFrecuencia(List<String> arrTerminos,Pagina pag){

        ArrayList<Terminoxpagina> arrTerm = new ArrayList<Terminoxpagina>();
        String palabra="";
        int frec = 0;
        for(int i=0;i<arrTerminos.size();i++)
        {
            palabra= arrTerminos.get(i);
            frec=1;
            for(int j=i+1;j<arrTerminos.size();j++)
            {
                if(palabra.equals(arrTerminos.get(j)))
                {
                    frec++;
                    arrTerminos.remove(j);
                    j--;
                }
            }

            Termino term = new Termino();
            term.setTermino(palabra);

            Terminoxpagina termXpag = new Terminoxpagina();
            termXpag.setFrecuencia(frec);
            termXpag.setTermino(term);
            termXpag.setPagina(pag);

            arrTerm.add(termXpag);
        }

        return arrTerm;

    }

    private void calcularPesos(ArrayList<Terminoxpagina> arrTermxPag){

        TerminoDao objTermDao = (TerminoDao)daoManager.getDao(TerminoDao.class);
        double cont =0.0;
        double factNorm = 0.0;

        for(Terminoxpagina t:arrTermxPag){

            /*if(t.getTermino().getTermino().length()>50){
                t.getTermino().setTermino(t.getTermino().getTermino().substring(0, 49));
            }*/

            List<Terminoxpagina> arrTotal= objTermDao.contarTermino(t);
            cont = t.getFrecuencia()/(arrTotal.size()+1);
            t.setPeso(cont);
            factNorm = factNorm + cont*cont;

            if(arrTotal.size()>0){
                t.getTermino().setIdtermino(arrTotal.get(0).getTermino().getIdtermino());
                actualizarTerminos(arrTotal,objTermDao);
            }
            else
            {
                objTermDao.insertarTermino(t.getTermino());
                t.getTermino().setIdtermino(t.getTermino().getIdtermino());
            }
        }

        factNorm = Math.sqrt(factNorm);

        for(Terminoxpagina ter:arrTermxPag){
            cont= ter.getPeso()/factNorm;
            ter.setPeso(cont);
        }
    }

        private void actualizarTerminos(List<Terminoxpagina> arrTermxPag,TerminoDao objTermDao){

        double factNorm=0.0;
        double peso=0.0;
        int tam= arrTermxPag.size();

        for(Terminoxpagina t:arrTermxPag){

           factNorm = t.getFrecuencia()/(tam*t.getPeso());
           peso = t.getFrecuencia()/((tam+1)*factNorm);
           t.setPeso(peso);
           objTermDao.actualizaTermino(t);
        }
    }

    private void guardarTerminos(ArrayList<Terminoxpagina> arrTerm){

        TerminoDao objTermDao = (TerminoDao)daoManager.getDao(TerminoDao.class);
        objTermDao.insertarTerminoxPagina(arrTerm);

    }

    private void eliminarPag(int intIdPag){
        PaginaDao objPaginaDao = (PaginaDao)daoManager.getDao(PaginaDao.class);
        objPaginaDao.eliminarPagTemp(intIdPag);
    }

}
